﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using Qas.CommonLogic;
using Qas.CommonLogic.BusinessObjects;
using System.Windows.Forms;

namespace Qas.CommonLogic.Business_Objects.Graph
{
    public class State
    {
        private List<Condition> conditionsField = new List<Condition>();
        private double weightField = 0;
        private State previousStateField;
        private List<Task> visitedTasks = new List<Task>();

        //PriorityQueue 

        public override string ToString()
        {
            string result = "State:";
            foreach (Condition condItem in this.Conditions)
            {
                result += condItem.ID.ToString() + "-";
            }

            return result;
        }

        public State(State state)
        {
            if (state == null)
            {
                throw new NullReferenceException();
            }
            else
            {
                this.previousState = state.previousState;
                this.visitedTasks = state.visitedTasks;
                this.Weight = state.Weight;
                this.Conditions = state.Conditions;
            }
        }

        public State()
        {
        }

        public State(List<Condition> conditions, double weight, State prevState, List<Task> tasks)
        {
            this.Conditions = conditions;

            if ((Weight == 0) || (weight < Weight))
            {
                Weight = weight;
                this.previousState = prevState;
            }

            this.Tasks = tasks;
        }

        public List<Condition> PostConditions()
        {
            if (this.Tasks == null)
            {
                return null;
            }
            else
            {
                List<Condition> postConditions = new List<Condition>();
                foreach (Task task in this.Tasks)
                {
                    postConditions.AddRange(task.PostConditions);
                }
                return postConditions;
            }
        }


        public override bool Equals(object obj)
        {
            State anotherState = obj as State;

            if (anotherState == null)
            {
                throw new NullReferenceException();
            }

            List<Condition> tmp = anotherState.Conditions;

            foreach (Condition cond in this.Conditions)
            {
                if (tmp.Contains(cond))
                {
                    tmp.Remove(cond);
                }
                else
                {
                    return false;
                }
            }

            return (tmp.Count == 0);
        }

        public double Weight
        {
            get
            {
                return this.weightField;
            }
            set
            {
                this.weightField = value;
            }
        }

        public List<Task> Tasks
        {
            get
            {
                return this.visitedTasks;
            }
            set
            {
                this.visitedTasks = value;
            }
        }

        public List<Condition> Conditions
        {
            get
            {
                return this.conditionsField;
            }
            set
            {
                this.conditionsField = value;
            }
        }

        public State previousState
        {
            get
            {
                return this.previousStateField;
            }
            set
            {
                this.previousStateField = value;
            }
        }

        //public Plan getTasks1()
        //{
        //    if (this.Task == null)
        //    {
        //        throw new NullReferenceException();
        //    }
        //    else
        //    {
        //        List<Task> tasks = new List<Task>();
        //        tasks.Add(this.Task);
        //        if (this.previousState.Conditions.Count != 0)
        //        {
        //            State state = new State(this.previousState);


        //            //List<Condition> conditions = new List<Condition>();

        //            while (state.previousState != null)
        //            {
        //                tasks.Add(state.Task);
        //                state = state.previousState;
        //            }
        //        }
        //        tasks.Reverse();


        //        Plan plan = new Plan(tasks);

        //        return plan;
        //    }
        //}

        public Plan getTasks()
        {
            if (this.visitedTasks == null)
            {
                throw new NullReferenceException();
            }
            else
            {
                Plan plan = new Plan();
                foreach (Task task in this.Tasks)
                {
                    plan.AddTask(task);
                }
                return plan;
            }
        }


        public bool ContatinsPreCondition(Task otherTask)
        {
            if (otherTask == null)
            {
                throw new NullReferenceException();
            }
            else
            {
                foreach (Task task in this.getTasks().Tasks)
                {
                    if (Condition.Subtraction(otherTask.PreConditions, task.PreConditions).Count == 0)
                    {
                        return true;
                    }
                }
                return false;
            }
        }

        public bool CoversPostConditions(Task otherTask)
        {
            if (otherTask == null)
            {
                throw new NullReferenceException();
            }
            else
            {
                List<Condition> conditions = new List<Condition>();
                foreach (Task task in this.getTasks().Tasks)
                {

                    conditions.AddRange(task.PostConditions);
                }

                if (Condition.Subtraction(otherTask.PreConditions, conditions).Count == 0)
                {
                    return true;
                }
                return false;
            }
        }

        private bool checkTask(Task task, List<Condition> conditions)
        {
            if (task.PreConditions.Count != 0)
            {
                if (Condition.Subtraction(task.PreConditions, conditions).Count == 0)
                {
                    return false;
                }
                else
                {
                    conditions.AddRange(task.PreConditions);
                }
            }
            return true;
        }
    }
}


//using System;
//using System.Collections.Generic;
//using System.Collections;
//using System.Linq;
//using System.Text;
//using Qas.CommonLogic;
//using Qas.CommonLogic.BusinessObjects;
//using System.Windows.Forms;

//namespace Qas.CommonLogic.Business_Objects.Graph
//{
//    public class State
//    {
//        private List<Condition> conditionsField;
//        private double weightField = 0;
//        private State previousStateField;
//        private List<Task> visitedTasks = new List<Task>();

//        //PriorityQueue 

//        public override string ToString()
//        {
//            string result = "State:";
//            foreach (Condition condItem in this.Conditions)
//            {
//                result += condItem.ID.ToString() + "-";
//            }

//            return result;
//        }


//        public State()
//        {
//        }

//        public State(State state)
//        {
//            if (state == null)
//            {
//                throw new NullReferenceException();
//            }
//            else
//            {
//                this.previousState = state.previousState;
//                this.visitedTasks = state.visitedTasks;
//                this.Weight = state.Weight;
//                this.Conditions = state.Conditions;
//            }
//        }

//        public State(List<Condition> conditions, double weight, State prevState, List<Task> tasks)
//        {
//            this.Conditions = conditions;

//            if ((Weight == 0) || (weight < Weight))
//            {
//                Weight = weight;
//                this.previousState = prevState;
//            }

//            this.Tasks = tasks;
//        }

//        public List<Condition> PostConditions()
//        {
//            if (this.Tasks == null)
//            {
//                return null;
//            }
//            else
//            {
//                List<Condition> postConditions = new List<Condition>();
//                foreach (Task task in this.Tasks)
//                {
//                    postConditions.AddRange(task.PostConditions);
//                }
//                return postConditions;
//            }
//        }


//        public override bool Equals(object obj)
//        {
//            State anotherState = obj as State;

//            if (anotherState == null)
//            {
//                throw new NullReferenceException();
//            }

//            List<Condition> tmp = anotherState.Conditions;

//            foreach (Condition cond in this.Conditions)
//            {
//                if (tmp.Contains(cond))
//                {
//                    tmp.Remove(cond);
//                }
//                else
//                {
//                    return false;
//                }
//            }

//            return (tmp.Count == 0);
//        }

//        public double Weight
//        {
//            get
//            {
//                return this.weightField;
//            }
//            set
//            {
//                this.weightField = value;
//            }
//        }

//        public List<Task> Tasks
//        {
//            get
//            {
//                return this.visitedTasks;
//            }
//            set
//            {
//                this.visitedTasks = value;
//            }
//        }

//        public List<Condition> Conditions
//        {
//            get
//            {
//                return this.conditionsField;
//            }
//            set
//            {
//                this.conditionsField = value;
//            }
//        }

//        public State previousState
//        {
//            get
//            {
//                return this.previousStateField;
//            }
//            set
//            {
//                this.previousStateField = value;
//            }
//        }

//        //public Plan getTasks1()
//        //{
//        //    if (this.Task == null)
//        //    {
//        //        throw new NullReferenceException();
//        //    }
//        //    else
//        //    {
//        //        List<Task> tasks = new List<Task>();
//        //        tasks.Add(this.Task);
//        //        if (this.previousState.Conditions.Count != 0)
//        //        {
//        //            State state = new State(this.previousState);


//        //            //List<Condition> conditions = new List<Condition>();

//        //            while (state.previousState != null)
//        //            {
//        //                tasks.Add(state.Task);
//        //                state = state.previousState;
//        //            }
//        //        }
//        //        tasks.Reverse();


//        //        Plan plan = new Plan(tasks);

//        //        return plan;
//        //    }
//        //}

//        public Plan getTasks()
//        {
//            if (this.visitedTasks == null)
//            {
//                throw new NullReferenceException();
//            }
//            else
//            {
//                Plan plan = new Plan();
//                foreach (Task task in this.Tasks)
//                {
//                    plan.AddTask(task);
//                }
//                return plan;
//            }
//        }


//        public bool ContatinsPreCondition(Task otherTask)
//        {
//            if (otherTask == null)
//            {
//                throw new NullReferenceException(); 
//            }
//            else
//            {
//                foreach (Task task in this.getTasks().Tasks)
//                {
//                    if (Condition.Subtraction(otherTask.PreConditions, task.PreConditions).Count == 0)
//                    {
//                        return true;
//                    }
//                }
//                return false;
//            }
//        }

//        public bool CoversPostConditions(Task otherTask)
//        {
//            if (otherTask == null)
//            {
//                throw new NullReferenceException();
//            }
//            else
//            {
//                List<Condition> conditions = new List<Condition>();
//                foreach (Task task in this.getTasks().Tasks)
//                {
                 
//                    conditions.AddRange(task.PostConditions);
//                }
                    
//                if (Condition.Subtraction(otherTask.PreConditions, conditions).Count == 0)
//                {
//                        return true;
//                }
//                return false;
//            }
//        }

//        private bool checkTask(Task task, List<Condition> conditions)
//        {
//            if (task.PreConditions.Count != 0)
//            {
//                if (Condition.Subtraction(task.PreConditions, conditions).Count == 0)
//                {
//                    return false;
//                }
//                else
//                {
//                    conditions.AddRange(task.PreConditions);
//                }
//            }
//            return true;
//        }
//    }
//}
